package 集合;
import java.util.*;
import 常用类库API.*;
/*
  Set接口
    1,无序的,不保证顺序
	2,不允许重复
  实现类
  HashSet  不需排序不保证顺序时使用
  TreeSet  需排序时使用
  LinkedHashSet 不需要排序，但要保证顺序使用
       linkedhashset，使用双重链接列表，定义了迭代顺序，即按照元素插上set的属性迭代
*/
public class X03Set接口
{
	public static void main(String[]args){
		//hashset();
		treeset();
	}
	/*
	  TreeSet 基于二叉树数据结构的有序集合
	  1，对象需要比较大小，通过对象比较器实现
	     自定义的类如需添加到TreeSet，要不实现Comparable接口，要不需要一个此类的对象比较器Comparator(传到构造方法里)
		 否则会报异常
	  2，对象比较器可以去除重复元素
	*/
	private static void treeset(){
		Cat c1=new Cat("huahua",1);
		Cat c2=new Cat("tom",2);
		Cat c3=new Cat("miaomiao",3);
		Cat c4=new Cat("huahua",1);
		TreeSet<Cat> tree=new TreeSet<>();//如果类没有实现comparable接口，构造方法里需要有比较器comparator的类对象作为参数
		tree.add(c1);
		tree.add(c2);
		tree.add(c3);
		tree.add(c4);//由于Cat类比较的是age，所有按age排序，age相同的会认为相同对象，(实际中应该以id之类的比较)，
		System.out.println(tree.size());
		for(Cat c:tree){
			System.out.println(c);
		}
	}
	
	/*
	 HashSet:
	   1，实现原理 基于哈希表(HashMap 数组+链表)实现
	       如何存储: 先计算对象hascode，然后对数组长度取余来确定对象存储位置，
		            余数相同的，以链表的形式存储在一个位置(第一个作为根，以后余数相同的作为next)
	   2,不允许重复，可以有一个null元素
	   3，不保证顺序恒久不变
	   4，存储对象时，把对象作为HashMap的key存储，value是一个固定不变的object对象
	   5,排除重复元素使用equals检查
	   6,判断对象是否是同一对象，1先判断hashcode>>不同，直接返回不同，相同的话进入下一步 2再判断equals  (根据需求重写这两个方法)
	*/
	private static void hashset(){
		Set<String> set=new HashSet<>();
		set.add("小明");
		set.add("小刘");
		set.add("韩梅梅");
		set.add("小张");
		System.out.println(set.size());
		set.add("小明");
		System.out.println(set.size());
		for(String s:set){
			System.out.println(s);
		}
		//由于hashset没有get方法，所以便利要先toarray,再用普通for(;;i++) get(i)
		//for each可以直接获得对象
		String[] strs=set.toArray(new String[]{});
		for(String s:strs){
			System.out.println(s);
		}
		Cat c1=new Cat("huahua",1);
		Cat c2=new Cat("tom",2);
		Cat c3=new Cat("miaomiao",3);
		Cat c4=new Cat("huahua",1);
		Set<Cat> cats=new HashSet<>();
		cats.add(c1);
		cats.add(c2);
		cats.add(c3);
		//如果属性相同的对象要想让程序当做相同的话，需要在类中重写hadhcode(计算hash)和equals(判断属性)方法
		cats.add(c4);//这里c4 虽然属性与c1相同，但不是同一对象，正常添加
		System.out.println(cats.size());
		cats.add(c1);//这样就重复了，添加不上了
		
	}
}
